package com.guit.hrms.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.guit.hrms.dto.UpdateDTO;
import com.guit.hrms.dto.UpdateOnboardingStatusDTO;
import com.guit.hrms.dto.interview.UpdateInterviewStatusDTO;
import com.guit.hrms.mapper.*;
import com.guit.hrms.po.Employee;
import com.guit.hrms.po.ToEmail;
import com.guit.hrms.po.department.Department;
import com.guit.hrms.po.academy.Academy;
import com.guit.hrms.po.interview.Interviewee;
import com.guit.hrms.po.interview.Onboarding;
import com.guit.hrms.po.onboarding.OnboardingVO;
import com.guit.hrms.po.otherDept.OtherDept;
import com.guit.hrms.po.position.Position;
import com.guit.hrms.po.resume.EmployeeResume;
import com.guit.hrms.po.resume.EmployeeResumeFile;
import com.guit.hrms.po.resume.WorkExperience;
import com.guit.hrms.po.utilsPO.PageBean;
import com.guit.hrms.service.OnboardingService;
import com.guit.hrms.utils.EmailUtil;
import com.guit.hrms.utils.ExcelUtil;
import com.guit.hrms.utils.MD5Util;
import com.guit.hrms.utils.ThreadLocalUtil;
import com.guit.hrms.vo.UpdateOnboardingStatusVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

@Service
public class OnboardingServiceImpl implements OnboardingService {

    @Autowired
    private OnboardingMapper onboardingMapper;
    @Autowired
    private IntervieweeMapper intervieweeMapper;
    @Autowired
    private RecruitmentMapper recruitmentMapper;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private AcademyMapper academyMapper;
    @Autowired
    private OtherDeptMapper otherDeptMapper;
    @Autowired
    private PositionMapper positionMapper;
    @Autowired
    private QueryMapper queryMapper;
    @Autowired
    private UpdateMapper updateMapper;
    @Autowired
    private EmpResumeMapper empResumeMapper;
    @Autowired
    private EmailUtil emailUtil;

    /**
     * 获取待办理入职的信息
     * @param page 当前页
     * @param pageSize 每页大小
     * @param onboardingTime 入职办理时间
     * @param onboardingPlace 入职办理地点
     * @return 待入职信息
     */
    @Override
    public PageBean getOnboarding(Integer page, Integer pageSize, LocalDateTime onboardingTime, String onboardingPlace, Integer status) {
        PageHelper.startPage(page, pageSize);
        List<OnboardingVO> onboardingList = onboardingMapper.getOfferResult(status, onboardingTime, onboardingPlace);
        Interviewee interviewee = null;
        Department department = null;
        Academy academy = null;
        OtherDept otherDept = null;
        Position position = null;
        String deptName = null;
        String positionName = null;
        Integer type = 0;
        List<OnboardingVO> offerList = new ArrayList<>();
        for (OnboardingVO onboardingVO : onboardingList) {
            interviewee = intervieweeMapper.getIntervieweeById(onboardingVO.getIntervieweeId());
            type = recruitmentMapper.getPlanTypeByPlanId(interviewee.getPlanId());
            if (type == 1){
                department = departmentMapper.getDepartmentByDeptNumber(interviewee.getDeptId());
                if (department != null){
                    deptName = department.getDeptName();
                } else {
                    throw new RuntimeException("部门不存在");
                }
                position = positionMapper.getPositionById2(interviewee.getPositionNumber(), type, department.getDeptId());
                if (position != null){
                    positionName = position.getPositionName();
                } else {
                    throw new RuntimeException("岗位不存在");
                }
            } else if (type == 2) {
                academy = academyMapper.getAcademyById(interviewee.getPlanId());
                if (academy != null){
                    deptName = academy.getAcademyName();
                } else {
                    throw new RuntimeException("部门不存在");
                }
                position = positionMapper.getPositionById2(interviewee.getPositionNumber(), type, academy.getAcademyId());
                if (position != null){
                    positionName = position.getPositionName();
                } else {
                    throw new RuntimeException("岗位不存在");
                }
            } else if (type == 3) {
                otherDept = otherDeptMapper.getOtherDeptById(interviewee.getPlanId());
                if (otherDept != null){
                    deptName = otherDept.getOtherDeptName();
                } else {
                    throw new RuntimeException("部门不存在");
                }
                position = positionMapper.getPositionById2(interviewee.getPositionNumber(), type, otherDept.getOtherDeptId());
                if (position != null){
                    positionName = position.getPositionName();
                } else {
                    throw new RuntimeException("岗位不存在");
                }
            } else {
                throw new RuntimeException("部门类型错误");
            }
            onboardingVO.setIntervieweeName(interviewee.getName());
            onboardingVO.setDeptId(interviewee.getDeptId());
            onboardingVO.setDeptName(deptName);
            onboardingVO.setPositionNumber(interviewee.getPositionNumber());
            onboardingVO.setPositionName(positionName);
            offerList.add(onboardingVO);
        }
        onboardingList.clear();
        onboardingList.addAll(offerList);
        Page<OnboardingVO> p = (Page<OnboardingVO>) onboardingList;
        return new PageBean(p.getTotal(), p.getResult());
    }

    /**
     * 更新入职状态
     * @param updateOnboardingStatusDTO 更新入职状态DTO
     * @return 结果
     */
    @Override
    @Transactional
    public List<UpdateOnboardingStatusVO> updateOnboardingStatus(UpdateOnboardingStatusDTO updateOnboardingStatusDTO) {
        Interviewee interviewee = null;
        Integer result = 0;
        Onboarding onboarding = null;
        List<UpdateOnboardingStatusVO> updateOnboardingStatusVOList = new ArrayList<>();
        UpdateOnboardingStatusVO updateOnboardingStatusVO = null;
        List<String> emails = new ArrayList<>();
        Map<String, Object> map = ThreadLocalUtil.get();
        String updateBy = map.get("employeeId").toString();
        for (Integer id : updateOnboardingStatusDTO.getIds()) {
            onboarding = onboardingMapper.getOnboardingById(id);
            if (onboarding == null) {
                throw new RuntimeException("入职信息不存在");
            }
            interviewee = intervieweeMapper.getIntervieweeById(onboarding.getIntervieweeId());
            if (interviewee == null) {
                throw new RuntimeException("面试者不存在");
            }
            if (updateOnboardingStatusDTO.getStatus() == 1) {
                result = onboardingMapper.updateOnboardingStatus(id, updateOnboardingStatusDTO.getStatus(), LocalDateTime.now(), updateBy);
                if (result == 0) {
                    throw new RuntimeException("更新入职状态失败");
                }
                Department department = null;
                Academy academy = null;
                OtherDept otherDept = null;
                String departmentName = null;
                String positionName = null;
                Position position = null;
                Integer deptId = null;
                result = intervieweeMapper.updateTryout(interviewee.getId(), updateOnboardingStatusDTO.getTryoutStartTime(), updateOnboardingStatusDTO.getTryoutEndTime(), updateOnboardingStatusDTO.getTryoutDuration());
                if (result == 0){
                    throw new RuntimeException("更新应聘者试用期失败");
                }
                result = positionMapper.updatePositionPerson(interviewee.getPositionNumber(), 1);
                if (result == 0){
                    throw new RuntimeException("更新职位人数失败");
                }
                Integer deptType = recruitmentMapper.getPlanTypeByPlanId(interviewee.getPlanId());
                if (deptType == 1){
                    department = departmentMapper.getDepartmentByDeptNumber(interviewee.getDeptId());
                    if (department != null){
                        departmentName = department.getDeptName();
                    } else {
                        throw new RuntimeException("部门不存在");
                    }
                    deptId = department.getDeptId();
                    position = positionMapper.getPositionById2(interviewee.getPositionNumber(), deptType, department.getDeptId());
                    if (position != null){
                        positionName = position.getPositionName();
                    } else {
                        throw new RuntimeException("岗位不存在");
                    }
                } else if (deptType == 2) {
                    academy = academyMapper.getAcademyById(interviewee.getPlanId());
                    if (academy != null){
                        departmentName = academy.getAcademyName();
                    } else {
                        throw new RuntimeException("部门不存在");
                    }
                    deptId = academy.getAcademyId();
                    position = positionMapper.getPositionById2(interviewee.getPositionNumber(), deptType, academy.getAcademyId());
                    if (position != null){
                        positionName = position.getPositionName();
                    } else {
                        throw new RuntimeException("岗位不存在");
                    }
                } else if (deptType == 3) {
                    otherDept = otherDeptMapper.getOtherDeptById(interviewee.getPlanId());
                    if (otherDept != null){
                        departmentName = otherDept.getOtherDeptName();
                    } else {
                        throw new RuntimeException("部门不存在");
                    }
                    deptId = otherDept.getOtherDeptId();
                    position = positionMapper.getPositionById2(interviewee.getPositionNumber(), deptType, otherDept.getOtherDeptId());
                    if (position != null){
                        positionName = position.getPositionName();
                    } else {
                        throw new RuntimeException("岗位不存在");
                    }
                } else {
                    throw new RuntimeException("部门类型错误");
                }

                //生成账号
                String employeeId;
                UpdateDTO updateDTO = new UpdateDTO();
                do {
                    do {
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < 7; i++) {
                            int digit = ThreadLocalRandom.current().nextInt(0, 10);
                            sb.append(digit);
                        }
                        employeeId = sb.toString();
                    } while (queryMapper.getById(employeeId) != null);
                    updateDTO.setEmployeeId(employeeId);
                    updateDTO.setPassword(MD5Util.encrypt("123456"));
                    result = updateMapper.createNewAccount(updateDTO);
                } while (result == 0);

                Employee employee = new Employee();
                BeanUtils.copyProperties(interviewee, employee);
                employee.setEmployeeId(employeeId);
                employee.setUsername(interviewee.getName());
                employee.setPhoneNumber(interviewee.getPhone());
                employee.setDepartment(deptId);
                employee.setPosition(position.getPositionId());
                employee.setDeptType(deptType);
                employee.setIntervieweeId(interviewee.getId());

                result = updateMapper.bindingAccount(employee);

                if (result == 0) {
                    throw new RuntimeException("账号绑定失败");
                } else {
                    updateDTO = new UpdateDTO();
                    updateDTO.setEmployeeId(employee.getEmployeeId());
                    updateDTO.setRoleId(2);
                    result = updateMapper.insertRole(updateDTO);
                    if (result == 0){
                        throw new RuntimeException("角色绑定失败");
                    }

                    EmployeeResume employeeResume = new EmployeeResume();
                    employeeResume.setEmployeeId(employeeId);
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月d日");

                    LocalDate currentDate = LocalDate.now();

                    String formattedDate = currentDate.format(formatter);

                    WorkExperience workExperience = new WorkExperience("桂林信息科技学院"+departmentName, positionName, formattedDate, "入职");
                    employeeResume.setWorkExperiences(Collections.singletonList(workExperience));

                    try {
                        EmployeeResumeFile employeeResumeFile = ExcelUtil.createResumeExcel(employeeResume);
                        employeeResumeFile.setEmployeeId(employee.getEmployeeId());
                        employeeResumeFile.setFileName(employee.getEmployeeId()+employee.getUsername()+"的履历");
                        employeeResumeFile.setUpdatedAt(LocalDateTime.now());
                        result = empResumeMapper.createEmpResume(employeeResumeFile);
                        if (result == 0) {
                            throw new RuntimeException("新增履历失败");
                        }
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }

                    emails = new ArrayList<>();
                    emails.add(interviewee.getEmail());
                    ToEmail toEmail = new ToEmail();
                    toEmail.setTos(emails.toArray(new String[0]));
                    toEmail.setSubject("入职结果通知");
                    toEmail.setContent("恭喜您入职成功，您的工号(账号)为： " + updateDTO.getEmployeeId() + " ， 密码为： 123456 ，请尽快登录系统！");
                    emailUtil.sendSimpleEmail(toEmail);
                }
                updateOnboardingStatusVO = new UpdateOnboardingStatusVO(interviewee.getId(), interviewee.getName(), departmentName, positionName, employeeId, "123456");
                updateOnboardingStatusVOList.add(updateOnboardingStatusVO);
            } else if (updateOnboardingStatusDTO.getStatus() == 2){
                result = onboardingMapper.updateOnboardingStatus(id, updateOnboardingStatusDTO.getStatus(), LocalDateTime.now(), updateBy);
                if (result == 0) {
                    throw new RuntimeException("更新入职状态失败");
                }
                UpdateInterviewStatusDTO updateInterviewStatusDTO = new UpdateInterviewStatusDTO();
                List<Integer> intervieweeIds = new ArrayList<>();
                intervieweeIds.add(interviewee.getId());
                updateInterviewStatusDTO.setIntervieweeIds(intervieweeIds);
                updateInterviewStatusDTO.setInterviewStatus(7);
                result = intervieweeMapper.updateInterviewStatus(updateInterviewStatusDTO);
                if (result == 0){
                    throw new RuntimeException("更新应聘者面试状态失败");
                }
                emails.add(interviewee.getEmail());
            }

        }
        if (updateOnboardingStatusDTO.getStatus() == 2){
//            emails = new ArrayList<>();
//            emails.add(interviewee.getEmail());
            ToEmail toEmail = new ToEmail();
            toEmail.setTos(emails.toArray(new String[0]));
            toEmail.setSubject("入职结果通知");
            toEmail.setContent("很抱歉，由于您没有在规定时间内入职，现已视您放弃入职！");
            emailUtil.sendSimpleEmail(toEmail);
            updateOnboardingStatusVOList = null;
        }
        return updateOnboardingStatusVOList;
    }
}
